﻿using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;


public class CameraAnimationCurve :MonoBehaviour
{
    #region helper class
    [Serializable]
    public class PositionCurve
    {
        public AnimationCurve x;
        public AnimationCurve y;
        public AnimationCurve z;
        public PositionCurve()
        {
            x = new AnimationCurve();
            y = new AnimationCurve();
            z = new AnimationCurve();
        }
    }

    [Serializable]
    public class RotateCurve
    {
        public AnimationCurve x;
        public AnimationCurve y;
        public AnimationCurve z;

        public RotateCurve()
        {
            x = new AnimationCurve();
            y = new AnimationCurve();
            z = new AnimationCurve();
        }
    }

    [Serializable]
    public class AnimationNode
    {
        public PositionCurve position;
        public RotateCurve rotate;
        public float startTime;
        public float endTime;
    }
    #endregion

    public GameObject controlObj;
    public List<AnimationNode> animationNodes = new List<AnimationNode>();


    public void MakeAnimationCurve(
         Vector3 startPos
        , Vector3 endPos
        , Vector3 startRotate
        , Vector3 endRotate
        , float durationTime=1f )
    {
        Keyframe[] posKeyX = { new Keyframe( 0f, startPos.x ), new Keyframe( durationTime, endPos.x ) };
        Keyframe[] posKeyY = { new Keyframe( 0f, startPos.y ), new Keyframe( durationTime, endPos.y ) };
        Keyframe[] posKeyZ = { new Keyframe( 0f, startPos.z ), new Keyframe( durationTime, endPos.z ) };

        Keyframe[] rotateKeyX = { new Keyframe( 0f, startRotate.x ), new Keyframe( durationTime, endRotate.x ) };
        Keyframe[] rotateKeyY = { new Keyframe( 0f, startRotate.y ), new Keyframe( durationTime, endRotate.y ) };
        Keyframe[] rotateKeyZ = { new Keyframe( 0f, startRotate.z ), new Keyframe( durationTime, endRotate.z ) };

        PositionCurve pc = new PositionCurve();
        pc.x.keys = posKeyX;
        pc.y.keys = posKeyY;
        pc.z.keys = posKeyZ;

        RotateCurve rc = new RotateCurve();
        rc.x.keys = rotateKeyX;
        rc.y.keys = rotateKeyY;
        rc.z.keys = rotateKeyZ;

        AnimationNode an = new AnimationNode();
        an.position = pc;
        an.rotate = rc;
        an.startTime = Time.time;
        an.endTime = Time.time + durationTime;

        animationNodes.Add( an );
    }

    List<AnimationNode> deadNodes = new List<AnimationNode>();
    List<AnimationNode> doNodes = new List<AnimationNode>();

    void Update()
    {
        PickupUsedNode();
        RemoveDeadNode();
        DoActiveNode();
    }

    void PickupUsedNode()
    {
        foreach( AnimationNode node in animationNodes )
        {
            if( Time.time>node.endTime )
            {
                deadNodes.Add( node );
            }
            else if( Time.time > node.startTime && Time.time <= node.endTime )
            {
                doNodes.Add( node );
            }
        }
    }

    void RemoveDeadNode()
    {
        foreach( AnimationNode node in deadNodes )
        {
            animationNodes.Remove( node );
        }
        deadNodes.Clear();
    }

    void DoActiveNode()
    {
        if( doNodes.Count >0 )
        {
            float totalPosX=0f;
            float totalPosY=0f;
            float totalPosZ=0f;

            float totalRotateX = 0f;
            float totatRotateY = 0f;
            float totalRotateZ = 0f;

            foreach( AnimationNode node in doNodes )
            {
                float durationTime = Time.time - node.startTime;
                PositionCurve pc = node.position;
                totalPosX += pc.x.Evaluate( durationTime );
                totalPosY += pc.y.Evaluate( durationTime );
                totalPosZ += pc.z.Evaluate( durationTime );

                RotateCurve rc = node.rotate;
                totalRotateX += rc.x.Evaluate( durationTime );
                totatRotateY += rc.y.Evaluate( durationTime );
                totalRotateZ += rc.z.Evaluate( durationTime );
            }

            Vector3 newPos = new Vector3( totalPosX, totalPosY, totalPosZ ) / doNodes.Count;
            Vector3 newRotate = new Vector3( totalRotateX, totatRotateY, totalRotateZ ) /doNodes.Count;

            controlObj.transform.position = newPos;
            controlObj.transform.rotation = Quaternion.Euler( newRotate );
        }

    }

    public void ReadKeyFramePosition()
    {

    }

    public void ReadKeyFrameRotate()
    {

    }



}
